﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using Altairis.FluffyCloud.Data;

namespace Altairis.FluffyCloud.Security {

    public static class AclEntryExtensionMethods {

        public static bool EvaluatePermissions(this IEnumerable<AclEntry> acl, string operation, string[] roles) {
            if (acl == null) throw new ArgumentNullException("accessList");
            if (operation == null) throw new ArgumentNullException("operation");
            if (string.IsNullOrWhiteSpace(operation)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "operation");
            if (roles == null) throw new ArgumentNullException("roles");
            if (roles.Length == 0) throw new ArgumentException("Value cannot be empty array", "roles");

            // Admins can do anything
            if (roles.Contains(Role.AdministratorsRoleName)) return true;

            // Get all ACL entries that apply (correct operation and applying to role user is member of)
            var filteredAcl = acl.Where(x => x.Operation.Equals(operation, StringComparison.CurrentCultureIgnoreCase) && roles.Contains(x.RoleName));

            // Deny has preference over allow
            if (filteredAcl.Any(x => !x.Action)) return false;
            return filteredAcl.Any(x => x.Action);
        }

        public static bool EvaluatePermissions(this IEnumerable<AclEntry> acl, string operation) {
            return acl.EvaluatePermissions(operation, Roles.GetRolesForUser());
        }

        public static bool EvaluateTopicPermissionsForCurrentUser(this Topic topic, string operation) {
            if (topic == null) throw new ArgumentNullException("topic");

            // Owners can do anything
            if (HttpContext.Current.Request.IsAuthenticated && topic.UserName.Equals(HttpContext.Current.User.Identity.Name, StringComparison.CurrentCultureIgnoreCase)) return true;

            // Otherwise use acl
            return topic.AccessList.EvaluatePermissions(operation);
        }
    }
}